Skip to main content

EQ Fee Projection

    function _getEquilibriumFee(
uint256 idealBalance,
uint256 beforeBalance,
uint256 amountSD
) internal pure returns (uint256, uint256) {
require(beforeBalance >= amountSD, "Interswap: not enough balance");
uint256 afterBalance = beforeBalance.sub(amountSD);

uint256 safeZoneMax = idealBalance.mul(DELTA_1).div(DENOMINATOR);
uint256 safeZoneMin = idealBalance.mul(DELTA_2).div(DENOMINATOR);

uint256 eqFee = 0;
uint256 protocolSubsidy = 0;

if (afterBalance >= safeZoneMax) {
// no fee zone, protocol subsidize it.
eqFee = amountSD.mul(PROTOCOL_SUBSIDY).div(DENOMINATOR);
protocolSubsidy = eqFee;
} else if (afterBalance >= safeZoneMin) {
// safe zone
uint256 proxyBeforeBalance = beforeBalance < safeZoneMax
? beforeBalance
: safeZoneMax;
eqFee = _getTrapezoidArea(
LAMBDA_1,
0,
safeZoneMax,
safeZoneMin,
proxyBeforeBalance,
afterBalance
);
} else {
// danger zone
if (beforeBalance >= safeZoneMin) {
// across 2 or 3 zones
// part 1
uint256 proxyBeforeBalance = beforeBalance < safeZoneMax
? beforeBalance
: safeZoneMax;
eqFee = eqFee.add(
_getTrapezoidArea(
LAMBDA_1,
0,
safeZoneMax,
safeZoneMin,
proxyBeforeBalance,
safeZoneMin
)
);
// part 2
eqFee = eqFee.add(
_getTrapezoidArea(
LAMBDA_2,
LAMBDA_1,
safeZoneMin,
0,
safeZoneMin,
afterBalance
)
);
} else {
// only in danger zone
// part 2 only
eqFee = eqFee.add(
_getTrapezoidArea(
LAMBDA_2,
LAMBDA_1,
safeZoneMin,
0,
beforeBalance,
afterBalance
)
);
}
}
return (eqFee, protocolSubsidy);
}